// <copyright file="CategoryController.cs" company="EnterpriseApi">
// Copyright (c) EnterpriseApi. All rights reserved.
// </copyright>

using EnterpriseApi.DTOs;
using EnterpriseApi.Models;
using EnterpriseApi.Services;
using Microsoft.AspNetCore.Mvc;

namespace EnterpriseApi.Controllers;

/// <summary>
/// 类别控制器，处理类别相关的HTTP请求
/// </summary>
[ApiController]
[Route("api/[controller]")]
public class CategoryController : ControllerBase
{
    private readonly ICategoryService _categoryService;
    private readonly ILogger<CategoryController> _logger;

    /// <summary>
    /// 初始化CategoryController的新实例
    /// </summary>
    /// <param name="categoryService">类别服务</param>
    /// <param name="logger">日志记录器</param>
    public CategoryController(ICategoryService categoryService, ILogger<CategoryController> logger)
    {
        _categoryService = categoryService ?? throw new ArgumentNullException(nameof(categoryService));
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
    }

    /// <summary>
    /// 获取所有类别
    /// </summary>
    /// <returns>类别列表</returns>
    [HttpGet]
    [ProducesResponseType(StatusCodes.Status200OK)]
    public async Task<ActionResult<IEnumerable<CategoryDTO>>> GetAllCategories()
    {
        try
        {
            var categories = await _categoryService.GetAllAsync();
            var categoryDTOs = categories.Select(category => new CategoryDTO
            {
                Id = category.Id,
                Name = category.Name,
                Description = category.Description,
                CreatedAt = category.CreatedAt,
                UpdatedAt = category.UpdatedAt,
                ProductCount = category.Products?.Count ?? 0
            });
            return Ok(categoryDTOs);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取所有类别时发生错误");
            return StatusCode(StatusCodes.Status500InternalServerError, "获取所有类别时发生错误");
        }
    }

    /// <summary>
    /// 根据ID获取类别
    /// </summary>
    /// <param name="id">类别ID</param>
    /// <returns>类别详情</returns>
    [HttpGet("{id}")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<ActionResult<CategoryDTO>> GetCategoryById(int id)
    {
        try
        {
            var category = await _categoryService.GetByIdAsync(id);
            if (category == null)
            {
                return NotFound();
            }

            var categoryDTO = new CategoryDTO
            {
                Id = category.Id,
                Name = category.Name,
                Description = category.Description,
                CreatedAt = category.CreatedAt,
                UpdatedAt = category.UpdatedAt,
                ProductCount = category.Products?.Count ?? 0
            };
            return Ok(categoryDTO);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取类别详情时发生错误");
            return StatusCode(StatusCodes.Status500InternalServerError, "获取类别详情时发生错误");
        }
    }

    /// <summary>
    /// 创建新类别
    /// </summary>
    /// <param name="category">类别信息</param>
    /// <returns>创建的类别</returns>
    [HttpPost]
    [ProducesResponseType(StatusCodes.Status201Created)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    public async Task<ActionResult<CategoryDTO>> CreateCategory([FromBody] Category category)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        try
        {
            category.CreatedAt = DateTime.UtcNow;
            category.UpdatedAt = DateTime.UtcNow;
            var createdCategory = await _categoryService.AddAsync(category);

            var categoryDTO = new CategoryDTO
            {
                Id = createdCategory.Id,
                Name = createdCategory.Name,
                Description = createdCategory.Description,
                CreatedAt = createdCategory.CreatedAt,
                UpdatedAt = createdCategory.UpdatedAt,
                ProductCount = createdCategory.Products?.Count ?? 0
            };
            return CreatedAtAction(nameof(GetCategoryById), new { id = createdCategory.Id }, categoryDTO);
        }
        catch (ArgumentException ex)
        {
            _logger.LogError(ex, "创建类别时发生错误");
            return BadRequest(ex.Message);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "创建类别时发生错误");
            return StatusCode(StatusCodes.Status500InternalServerError, "创建类别时发生错误");
        }
    }

    /// <summary>
    /// 更新类别信息
    /// </summary>
    /// <param name="id">类别ID</param>
    /// <param name="category">更新的类别信息</param>
    /// <returns>更新后的类别</returns>
    [HttpPut("{id}")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<ActionResult<CategoryDTO>> UpdateCategory(int id, [FromBody] Category category)
    {
        if (id != category.Id)
        {
            return BadRequest("类别ID不匹配");
        }

        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        try
        {
            var existingCategory = await _categoryService.GetByIdAsync(id);
            if (existingCategory == null)
            {
                return NotFound();
            }

            category.UpdatedAt = DateTime.UtcNow;
            var updatedCategory = await _categoryService.UpdateAsync(category);

            var categoryDTO = new CategoryDTO
            {
                Id = updatedCategory.Id,
                Name = updatedCategory.Name,
                Description = updatedCategory.Description,
                CreatedAt = updatedCategory.CreatedAt,
                UpdatedAt = updatedCategory.UpdatedAt,
                ProductCount = updatedCategory.Products?.Count ?? 0
            };
            return Ok(categoryDTO);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "更新类别信息时发生错误");
            return StatusCode(StatusCodes.Status500InternalServerError, "更新类别信息时发生错误");
        }
    }

    /// <summary>
    /// 删除类别
    /// </summary>
    /// <param name="id">类别ID</param>
    /// <returns>删除结果</returns>
    [HttpDelete("{id}")]
    [ProducesResponseType(StatusCodes.Status204NoContent)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    public async Task<IActionResult> DeleteCategory(int id)
    {
        try
        {
            var category = await _categoryService.GetByIdAsync(id);
            if (category == null)
            {
                return NotFound();
            }

            // 检查类别下是否有产品
            if (category.Products != null && category.Products.Any())
            {
                return BadRequest("该类别下有产品，不能删除");
            }

            await _categoryService.DeleteAsync(id);
            return NoContent();
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "删除类别时发生错误");
            return StatusCode(StatusCodes.Status500InternalServerError, "删除类别时发生错误");
        }
    }

    /// <summary>
    /// 根据名称获取类别
    /// </summary>
    /// <param name="name">类别名称</param>
    /// <returns>类别详情</returns>
    [HttpGet("name/{name}")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<ActionResult<CategoryDTO>> GetCategoryByName(string name)
    {
        try
        {
            var category = await _categoryService.GetByNameAsync(name);
            if (category == null)
            {
                return NotFound();
            }

            var categoryDTO = new CategoryDTO
            {
                Id = category.Id,
                Name = category.Name,
                Description = category.Description,
                CreatedAt = category.CreatedAt,
                UpdatedAt = category.UpdatedAt,
                ProductCount = category.Products?.Count ?? 0
            };
            return Ok(categoryDTO);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "根据名称获取类别时发生错误");
            return StatusCode(StatusCodes.Status500InternalServerError, "根据名称获取类别时发生错误");
        }
    }

    /// <summary>
    /// 检查类别名称是否已存在
    /// </summary>
    /// <param name="name">类别名称</param>
    /// <returns>是否存在的布尔值</returns>
    [HttpGet("exists/{name}")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    public async Task<ActionResult<bool>> IsCategoryNameExists(string name)
    {
        try
        {
            var exists = await _categoryService.IsNameExistsAsync(name);
            return Ok(exists);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "检查类别名称是否存在时发生错误");
            return StatusCode(StatusCodes.Status500InternalServerError, "检查类别名称是否存在时发生错误");
        }
    }
}